package cn.com.hhrcw.web;

import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.mapstruct.CvResumeStatisticsConvert;
import cn.com.hhrcw.params.CvResumeStatisticsParams;
import cn.com.hhrcw.params.StatisticsInfoParams;
import cn.com.hhrcw.service.*;
import cn.com.hhrcw.vo.*;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.aspect.annotation.PermissionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;

/**
 * 数据报表
 *
 * @program: recruit-boot-parent
 * @description: 招聘数据统计
 * @author: JD
 * @create: 2020-11-13 10:31
 **/
@RestController
@RequestMapping("/admin/statistics")
@Slf4j
public class AdminStatisticsController {

    @Autowired
    private ICvResumeStatisticsService cvResumeStatisticsService;

    @Autowired
    private CvResumeStatisticsConvert cvResumeStatisticsConvert;

    @Autowired
    private IOpDeliveryHistoryService deliveryHistoryService;

    @Autowired
    private IOpJobService jobService;

    @Autowired
    private IOpEntryHistoryService entryHistoryService;

    @Autowired
    private IOpInterviewHistoryService interviewHistoryService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    AdminService enterpriseService;

    @Autowired
    ISysUserDepartService userDepartService;

    @Autowired
    private IEnInfoService enInfoService;

    /**
     * 招聘报表-招聘进度及发布岗位-下面的列表
     *
     * @param params
     * @return
     */
    @GetMapping("/jobInfos")
    public Result<Page<JobsStatisticsVO>> getStatisticsInfo(StatisticsInfoParams params) {
        LambdaQueryChainWrapper<OpJob> wrapper = this.jobService.lambdaQuery();
        if (StringUtils.isNotBlank(params.getJobName())) {
            wrapper.like(OpJob::getJobName, params.getJobName());
        }
        if (params.getStartTime() != null) {
            wrapper.ge(OpJob::getCreateTime, params.getStartTime());
        }
        if (params.getEndTime() != null) {
            wrapper.le(OpJob::getCreateTime, cn.hutool.core.date.DateUtil.endOfDay(cn.hutool.core.date.DateUtil.parse(params.getEndTime())));
        }
        IPage<OpJob> page = wrapper.eq(OpJob::getDelFlag, false).page(params.page());
        IPage<JobsStatisticsVO> convert = page.convert(e -> {
            JobsStatisticsVO vo = new JobsStatisticsVO();
            EnInfo enInfo = enInfoService.getById(e.getCompanyId());
            if (enInfo == null) {
                enInfo = new EnInfo();
            }
            vo.setComName(enInfo.getEnName());
            vo.setJobId(e.getId());
            vo.setJobName(e.getJobName());
            vo.setJobTime(e.getCreateTime());
            vo.setState(e.getDelFlag() ? 2 : e.getRecruitmentState());
            vo.setPlaneCount(e.getNeedCount());

            vo.setDeCount(0);
            vo.setFirstScrCount(0);
            vo.setScreenCount(0);
            vo.setViewCount(0);
            vo.setEntryCount(0);
            vo.setNotCount(0);
            vo.setOfferCount(0);

            //通过初筛
            List<OpDeliveryHistory> deliveryHistories = this.deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getDelFlag, false).eq(OpDeliveryHistory::getScreenFlag, true).eq(OpDeliveryHistory::getJobId, e.getId()).list();
            vo.setDeCount(deliveryHistories.size());
            long firstScrCount = deliveryHistories.stream().filter(history -> history.getState() >= 3).count();
            vo.setFirstScrCount((int) firstScrCount);
            vo.setScreenCount(deliveryHistories.size());
            //面试
            List<OpInterviewHistory> interviewHistories = interviewHistoryService.lambdaQuery().eq(OpInterviewHistory::getJobId, e.getId()).list();
            vo.setViewCount(CollectionUtils.isEmpty(interviewHistories) ? 0 : interviewHistories.size());
            //已入职
            long entryCount = deliveryHistories.stream().filter(history -> history.getState() == 6).count();
            vo.setEntryCount((int) entryCount);
            vo.setNotCount(e.getNeedCount() - (int) entryCount);
            //已发offer
            long offerCount = deliveryHistories.stream().filter(history -> ArrayUtil.contains(new int[]{5}, history.getState())).count();
            vo.setOfferCount((int) offerCount);
            vo.setCompletionRate(NumberUtil.round(NumberUtil.div(vo.getEntryCount(), e.getNeedCount()), 2));
            return vo;
        });
        return Result.ok((Page) convert);
    }

    /**
     * 招聘报表-招聘环节分析-各个职位信息统计
     * 面试通过率=反馈结果通过人数/接受面试总数
     *
     * @param params
     * @return
     */
    @GetMapping("/jobAnalysisInfo")
    public Result<Page<JobAnalysisVO>> jobAnalysisInfo(StatisticsInfoParams params) {
        LambdaQueryChainWrapper<OpJob> wrapper = this.jobService.lambdaQuery();
        if (StringUtils.isNotBlank(params.getJobName())) {
            wrapper.like(OpJob::getJobName, params.getJobName());
        }
        if (params.getStartTime() != null) {
            wrapper.ge(OpJob::getCreateTime, params.getStartTime());
        }
        if (params.getEndTime() != null) {
            wrapper.le(OpJob::getCreateTime, cn.hutool.core.date.DateUtil.endOfDay(cn.hutool.core.date.DateUtil.parse(params.getEndTime())));
        }
        IPage<OpJob> page = wrapper.eq(OpJob::getDelFlag, false).page(params.page());
        IPage<JobAnalysisVO> convert = page.convert(e -> {
            JobAnalysisVO vo = new JobAnalysisVO();
            EnInfo enInfo = enInfoService.getById(e.getCompanyId());
            if (enInfo == null) {
                enInfo = new EnInfo();
            }
            vo.setComName(enInfo.getEnName());
            vo.setComId(e.getCompanyId());
            vo.setJobId(e.getId());
            vo.setJobName(e.getJobName());
            vo.setJobTime(e.getCreateTime());
            vo.setState(e.getDelFlag() ? 2 : e.getRecruitmentState());
            vo.setFirstScrRate(BigDecimal.ZERO);
            vo.setViewRate(BigDecimal.ZERO);
            vo.setPositionRate(BigDecimal.ZERO);
            vo.setAdoptRate(BigDecimal.ZERO);
            vo.setEmployRate(BigDecimal.ZERO);
            vo.setLossRate(BigDecimal.ZERO);

            //通过初筛
            List<OpDeliveryHistory> deliveryHistories = this.deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getJobId, e.getId()).eq(OpDeliveryHistory::getScreenFlag, true).list();
            long firstScrCount = deliveryHistories.stream().filter(history -> history.getState() >= 3).count();
            vo.setFirstScrCount((int) firstScrCount);
            //初筛通过率
            if (deliveryHistories.size() > 0) {
                vo.setFirstScrRate(NumberUtil.round(NumberUtil.div(firstScrCount, deliveryHistories.size()), 2));
            }
            //面试
            List<OpInterviewHistory> interviewHistories = interviewHistoryService.lambdaQuery().eq(OpInterviewHistory::getJobId, e.getId()).list();
            vo.setViewCount(CollectionUtils.isEmpty(interviewHistories) ? 0 : interviewHistories.size());
            //邀约面试率   面试邀请数量/通过初筛数量
            if (firstScrCount > 0) {
                vo.setViewRate(NumberUtil.round(NumberUtil.div(interviewHistories.size(), firstScrCount), 2));
            }
            //已面试数量
            long alreadyViewCount = interviewHistories.stream().filter(history -> history.getOutLineState() == 1 && history.getViewResult() != null).count();
            vo.setAlreadyViewCount((int) alreadyViewCount);
            //接收面试数量
            long adoptCount = interviewHistories.stream().filter(history -> history.getViewResult() != null && history.getViewResult() == 0).count();
            vo.setAdoptCount((int) adoptCount);
            //面试通过率  反馈结果通过人数/接受面试总数
            long accept = interviewHistories.stream().filter(history -> history.getOutLineState() == 1).count();
            if (accept > 0) {
                vo.setAdoptRate(NumberUtil.round(NumberUtil.div(adoptCount, accept), 2));
            }
            //录用
            List<OpEntryHistory> entryHistories = this.entryHistoryService.lambdaQuery().eq(OpEntryHistory::getJobId, e.getId()).list();
            vo.setEmployCount(entryHistories.size());
            //录用率  入职邀请数量/面试总数量
            if (interviewHistories.size() > 0) {
                vo.setEmployRate(NumberUtil.round(NumberUtil.div(entryHistories.size(), interviewHistories.size()), 2));
            }
            long entryCount = deliveryHistories.stream().filter(history -> history.getState() == 6).count();
            vo.setEntryCount((int) entryCount);
            long entryAccept = entryHistories.stream().filter(history -> history.getAcceptFlag() == 1).count();
            //到岗率   已入职数量/接受入职邀请数量
            if (entryAccept > 0) {
                vo.setPositionRate(NumberUtil.round(NumberUtil.div(entryCount, entryAccept), 2));
            }
            long lossCount = entryHistories.stream().filter(history -> history.getAcceptFlag() == 2).count();
            vo.setLossCount((int) lossCount);
            //流失率   未接受入职邀请数量/总入职邀请数量
            if (entryHistories.size() > 0) {
                vo.setLossRate(NumberUtil.round(NumberUtil.div(lossCount, entryHistories.size()), 2));
            }
            return vo;
        });
        return Result.ok((Page) convert);
    }

    /**
     * 招聘报表-招聘环节分析-初筛淘汰环节分析
     *
     * @param dataType 查询范围，true本年度，false或者空查询所有
     * @return
     */
    @GetMapping("/eliminateReasonInfo")
    public Result<EliminateReasonVO> eliminateReasonInfo(Boolean dataType) {
        EliminateReasonVO res = new EliminateReasonVO();
        res.setExperienceCount(0);
        res.setTechnologyCount(0);
        res.setSalaryCount(0);
        res.setEducationCount(0);
        res.setIndustryCount(0);
        res.setTypeCount(0);
        List<OpDeliveryHistory> list = this.deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getDelFlag, false).eq(OpDeliveryHistory::getState, 2).isNotNull(OpDeliveryHistory::getInappropriateInfo).list();
        if (CollUtil.isEmpty(list)) {
            return Result.ok(res);
        }
        /*
            不合适原因
            0:工作经验不满足要求数量
            1:技术不符合岗位要求
            2:薪资不匹配
            3:学历不匹配
            4:行业不匹配
            5:招聘类型不匹配
            * */
        long experienceCount = list.stream().filter(e -> StrUtil.equals(e.getInappropriateInfo(), "0")).count();
        long technologyCount = list.stream().filter(e -> StrUtil.equals(e.getInappropriateInfo(), "1")).count();
        long salaryCount = list.stream().filter(e -> StrUtil.equals(e.getInappropriateInfo(), "2")).count();
        long educationCount = list.stream().filter(e -> StrUtil.equals(e.getInappropriateInfo(), "3")).count();
        long industryCount = list.stream().filter(e -> StrUtil.equals(e.getInappropriateInfo(), "4")).count();
        long typeCount = list.stream().filter(e -> StrUtil.equals(e.getInappropriateInfo(), "5")).count();
        res.setExperienceCount((int) experienceCount);
        res.setTechnologyCount((int) technologyCount);
        res.setSalaryCount((int) salaryCount);
        res.setEducationCount((int) educationCount);
        res.setIndustryCount((int) industryCount);
        res.setTypeCount((int) typeCount);
        return Result.ok(res);
    }

    /**
     * 招聘报表-流失淘汰环节分析
     *
     * @param dataType 查询范围,true本年度，false或者空查询所有
     * @return
     */
    @GetMapping("/eliminateInfo")
    public Result<EliminateInfo> eliminateInfo(Boolean dataType) {
        EliminateInfo info = new EliminateInfo();
        info.setPreliminary(BigDecimal.ZERO);
        info.setView(BigDecimal.ZERO);
        info.setSys(BigDecimal.ZERO);
        List<OpDeliveryHistory> list = this.deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getDelFlag, false).list();
        if (CollUtil.isEmpty(list)) {
            return Result.ok(info);
        }
        //通过系统筛选
        long pass = list.stream().filter(e -> e.getScreenFlag()).count();
        //被系统过滤
        long sys = list.stream().filter(e -> !e.getScreenFlag()).count();
        //初筛淘汰
        long first = list.stream().filter(e -> e.getState() == 2 && e.getScreenFlag()).count();
        //面试淘汰
        long view = list.stream().filter(e -> e.getState() == 10 && e.getScreenFlag()).count();
        long viewTotal = list.stream().filter(e -> e.getState() >= 4 && e.getScreenFlag()).count();
        if (pass > 0) {
            info.setPreliminary(NumberUtil.round(NumberUtil.div(first, pass), 2));
        }
        if (viewTotal > 0) {
            info.setView(NumberUtil.round(NumberUtil.div(view, viewTotal), 2));
        }
        info.setSys(NumberUtil.round(NumberUtil.div(sys, list.size()), 2));

        return Result.ok(info);
    }

    /**
     * 招聘报表-招聘进度
     *
     * @return
     */
    @GetMapping("/progress")
    public Result<IndexProgressVO> progress() {
        IndexProgressVO vo = new IndexProgressVO();
        vo.setOnLineJobCount(0);
        vo.setPlanCount(0);
        vo.setSurplusCount(0);
        vo.setScreenCount(0);
        vo.setFirstStepScreenCount(0);
        vo.setInterviewCount(0);
        vo.setAlreadyInterviewCount(0);
        vo.setAlreadyNoticeCount(0);
        vo.setAlreadyEntryCount(0);
        List<OpJob> jobs = this.jobService.lambdaQuery().eq(OpJob::getDelFlag, false).eq(OpJob::getRecruitmentState, 0).list();
        if (CollUtil.isNotEmpty(jobs)) {
            vo.setOnLineJobCount(jobs.size());
            Integer planCount = jobs.stream().map(OpJob::getNeedCount).reduce(0, Integer::sum);
            vo.setPlanCount(planCount);
            List<OpDeliveryHistory> histories = this.deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getDelFlag, false)
                    .in(OpDeliveryHistory::getJobId, jobs.stream().map(OpJob::getId).toArray())
                    .select(OpDeliveryHistory::getState, OpDeliveryHistory::getId, OpDeliveryHistory::getScreenFlag).list();
            Integer hired = (int) histories.stream().filter(e -> e.getState() == 6).count();
            vo.setSurplusCount(planCount - hired);
            Integer screenCount = (int) histories.stream().filter(e -> e.getScreenFlag()).count();
            vo.setScreenCount(screenCount);
            Integer firstStepScreenCount = (int) histories.stream().filter(e -> e.getState() > 2 && e.getScreenFlag()).count();
            vo.setFirstStepScreenCount(firstStepScreenCount);
            Integer interviewCount = (int) histories.stream().filter(e -> ArrayUtil.contains(new int[]{4, 5, 6, 8, 9, 10}, e.getState())).count();
            vo.setInterviewCount(interviewCount);
            Integer alreadyInterviewCount = (int) histories.stream().filter(e -> ArrayUtil.contains(new int[]{5, 6, 8, 9, 10}, e.getState())).count();
            vo.setAlreadyInterviewCount(alreadyInterviewCount);
            Integer alreadyNoticeCount = (int) histories.stream().filter(e -> ArrayUtil.contains(new int[]{5, 6, 8}, e.getState())).count();
            vo.setAlreadyNoticeCount(alreadyNoticeCount);
            Integer alreadyEntryCount = (int) histories.stream().filter(e -> ArrayUtil.contains(new int[]{6}, e.getState())).count();
            vo.setAlreadyEntryCount(alreadyEntryCount);
        }
        return Result.ok(vo);
    }

    /**
     * 招聘报表-招聘环节分析-招聘漏斗
     *
     * @param dataType 查询范围,true本年度，false或者空查询所有
     * @return
     */
    @GetMapping("/funnelInfo")
    public Result<FunnelInfoVO> funnelInfo(Boolean dataType) {
        FunnelInfoVO vo = new FunnelInfoVO();
        vo.setScreenCount(0);
        vo.setFirstScreenCount(0);
        vo.setInviteViewCount(0);
        vo.setJoinViewCount(0);
        vo.setSimulationCount(0);
        vo.setOfferCount(0);
        vo.setEntryCount(0);
        List<OpJob> jobs = this.jobService.lambdaQuery().eq(OpJob::getDelFlag, false).eq(OpJob::getRecruitmentState, 0).list();
        if (CollUtil.isNotEmpty(jobs)) {
            List<OpDeliveryHistory> histories = this.deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getDelFlag, false)
                    .in(OpDeliveryHistory::getJobId, jobs.stream().map(OpJob::getId).toArray())
                    .select(OpDeliveryHistory::getState, OpDeliveryHistory::getId, OpDeliveryHistory::getScreenFlag).list();
            //筛选简历
            Integer screenCount = (int) histories.stream().filter(e -> e.getScreenFlag()).count();
            vo.setScreenCount(screenCount);
            //初筛通过
            Integer firstStepScreenCount = (int) histories.stream().filter(e -> e.getState() > 2 && e.getScreenFlag()).count();
            vo.setFirstScreenCount(firstStepScreenCount);
            //面试数量
            Integer interviewCount = (int) histories.stream().filter(e -> ArrayUtil.contains(new int[]{4, 5, 6, 8, 9, 10}, e.getState())).count();
            vo.setInviteViewCount(interviewCount);
            //参加面试数量
            Integer alreadyInterviewCount = (int) histories.stream().filter(e -> ArrayUtil.contains(new int[]{5, 6, 8, 9, 10}, e.getState())).count();
            vo.setJoinViewCount(alreadyInterviewCount);
            //拟录用
            Integer passView = (int) histories.stream().filter(e -> ArrayUtil.contains(new int[]{5, 6, 9}, e.getState())).count();
            vo.setSimulationCount(passView);
            //发offer数量
            Integer alreadyNoticeCount = (int) histories.stream().filter(e -> ArrayUtil.contains(new int[]{5, 6, 8}, e.getState())).count();
            vo.setOfferCount(alreadyNoticeCount);
            //入职数量
            Integer alreadyEntryCount = (int) histories.stream().filter(e -> ArrayUtil.contains(new int[]{6}, e.getState())).count();
            vo.setEntryCount(alreadyEntryCount);
        }
        return Result.ok(vo);
    }

    /**
     * 数据报表-招聘进度及发布岗位-性别需求
     *
     * @return
     */
    @GetMapping("/sexInfo")
    public Result<SexInfoVO> sexInfo() {
        List<OpJob> jobs = jobService.lambdaQuery().eq(OpJob::getDelFlag, false).eq(OpJob::getRecruitmentState, 0).select(OpJob::getJobSex).list();
        SexInfoVO vo = new SexInfoVO();
        vo.setManCount(BigDecimal.ZERO);
        vo.setWomanCount(BigDecimal.ZERO);
        vo.setUnlimited(BigDecimal.ZERO);
        if (CollUtil.isNotEmpty(jobs)) {
            long man = jobs.stream().filter(e -> e.getJobSex() == 1).count();
            long woman = jobs.stream().filter(e -> e.getJobSex() == 2).count();
            long unlimited = jobs.stream().filter(e -> e.getJobSex() == 0).count();
            long total = man + woman + unlimited;
            vo.setManCount(NumberUtil.round(NumberUtil.div(man, total), 2));
            vo.setWomanCount(NumberUtil.round(NumberUtil.div(woman, total), 2));
            vo.setUnlimited(NumberUtil.round(NumberUtil.div(unlimited, total), 2));
        }
        return Result.ok(vo);
    }

    /**
     * 数据报表-招聘进度及发布岗位-学历要求
     *
     * @return
     */
    @GetMapping("/eduInfo")
    public Result<EduInfoVO> eduInfo() {
        List<OpJob> jobs = jobService.lambdaQuery().eq(OpJob::getDelFlag, false).eq(OpJob::getRecruitmentState, 0).list();
        EduInfoVO vo = new EduInfoVO();
        int a =2;
        int b =3;
        int c =4;
        int d =5;
        int f =6;
        int g =7;

        if (!CollectionUtils.isEmpty(jobs)) {
            jobs.forEach(e -> {
                //学历要求 0 初中  1 高中 2 中专/中技 3 大专 4 本科 5 硕士 6 MBA/EMBA 7 博士
                if (e.getEduLevel() != null) {
                    int level = e.getEduLevel();
                    if (level == 0) {
                        vo.setMiddle(vo.getMiddle() + 1);
                    } else if (level == 1) {
                        vo.setHigh(vo.getHigh() + 1);
                    } else if (level == a) {
                        vo.setSecondary(vo.getSecondary() + 1);
                    } else if (level == b) {
                        vo.setJuniorCollege(vo.getJuniorCollege() + 1);
                    } else if (level == c) {
                        vo.setUniversity(vo.getUniversity() + 1);
                    } else if (level == d) {
                        vo.setMaster(vo.getMaster() + 1);
                    } else if (level == f) {
                        vo.setMbaAndEmba(vo.getMbaAndEmba() + 1);
                    } else if (level == g) {
                        vo.setDoctor(vo.getDoctor() + 1);
                    }
                }
            });
        }
        return Result.ok(vo);
    }

    /**
     * 数据报表-招聘进度及发布岗位-年龄要求
     *
     * @return
     */
    @SneakyThrows
    @GetMapping("/ageInfo")
    public Result<AgeInfoVO> ageInfo() {
        List<OpJob> jobs = jobService.lambdaQuery().eq(OpJob::getDelFlag, false).eq(OpJob::getRecruitmentState, 0).list();
        AgeInfoVO vo = new AgeInfoVO();
        Field[] fields = AgeInfoVO.class.getDeclaredFields();
        for (Field field : fields) {
            String name = field.getName();
            Integer value = Integer.valueOf(name.substring(2));
            long count = jobs.stream().filter(e -> e.getJobMaxAge().equals(value)).count();
            ReflectUtil.setFieldValue(vo, field, count);
        }
        return Result.ok(vo);
    }

    /**
     * 数据报表-招聘进度及发布岗位-工作经验要求
     *
     * @return
     */
    @SneakyThrows
    @GetMapping("/workYearsInfo")
    public Result<WorkYearsInfoVO> workYearsInfo() {
        List<OpJob> jobs = jobService.lambdaQuery().eq(OpJob::getDelFlag, false).eq(OpJob::getRecruitmentState, 0).list();
        WorkYearsInfoVO vo = new WorkYearsInfoVO();
        Field[] fields = vo.getClass().getDeclaredFields();
        Map<Integer, Field> fieldMap = Maps.newTreeMap();
        for (Field field : fields) {
            String name = field.getName();
            Integer value = Integer.valueOf(name.substring(2));
            fieldMap.put(value, field);
        }
        Set<Map.Entry<Integer, Field>> entries = fieldMap.entrySet();
        int start = 0;
        for (Map.Entry<Integer, Field> entry : entries) {
            long count = 0;
            if (entry.getKey() == 999) {
                count = jobs.stream().filter(e -> e.getMaxExperience() == 999 && e.getMinExperience() == 0).count();
            } else {
                Integer end = entry.getKey();
                int start1 = start;
                count = jobs.stream().filter(e -> e.getMinExperience() >= start1 && e.getMaxExperience() <= end).count();
            }
            Field field = entry.getValue();
            ReflectUtil.setFieldValue(vo, field, count);
            start = entry.getKey();
        }
        return Result.ok(vo);
    }

    /**
     * 数据报表-简历量统计
     *
     * @return
     */
    @GetMapping("/sevenResumeInfo")
    public Result<SevenDayResumeVO> sevenDayInfo() {
        SevenDayResumeVO vo = new SevenDayResumeVO();
        vo.setSevenList(Lists.newArrayList());
        vo.setSevenNewMap(Maps.newHashMap());
        vo.setSevenTotalMap(Maps.newHashMap());
        List<CvResumeStatistics> list = this.cvResumeStatisticsService.lambdaQuery().orderByDesc(CvResumeStatistics::getId).last("limit 7").list();
        for (int i = 0; i < list.size(); i++) {
            CvResumeStatistics statistics = list.get(i);
            vo.getSevenList().add(cn.hutool.core.date.DateUtil.format(statistics.getCreateTime(), "yyyy-MM-dd"));
            vo.getSevenTotalMap().put(i, statistics.getTotal());
            vo.getSevenNewMap().put(i, statistics.getTotalThisDay());
        }
        return Result.ok(vo);
    }

    /**
     * 数据报表-简历量统计-下面的列表
     *
     * @param params 请求参数
     * @return
     */
    @GetMapping(value = "/listResume")
    @AutoLog("-分页列表查询")
    @ApiOperation(value = "分页列表查询", notes = "分页列表查询")
    @PermissionData
    public Result<Page<CvResumeStatisticsVO>> list(CvResumeStatisticsParams params, HttpServletRequest request) {
        LambdaQueryWrapper<CvResumeStatistics> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CvResumeStatistics::getDelFlag, false);
        if (params.getStartTime() != null) {
            queryWrapper.ge(CvResumeStatistics::getCreateTime, params.getStartTime());
        }
        if (params.getEndTime() != null) {
            DateTime end = cn.hutool.core.date.DateUtil.endOfDay(cn.hutool.core.date.DateUtil.parseDate(params.getEndTime()));
            queryWrapper.le(CvResumeStatistics::getCreateTime, end);
        }
        queryWrapper.orderByDesc(CvResumeStatistics::getCreateTime);
        IPage<CvResumeStatistics> page = cvResumeStatisticsService.page(params.page(), queryWrapper);
        //分页结果转换器
        Function<CvResumeStatistics, CvResumeStatisticsVO> fun = cvResumeStatistics -> cvResumeStatisticsConvert.toVO(cvResumeStatistics);
        return Result.ok((Page) page.convert(fun));
    }
}
